package com.jeequan.jeepay.mgr.ctrl.report;

import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.entity.PayOrderFlow;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.mgr.rqrs.AccountForMchRq;
import com.jeequan.jeepay.mgr.rqrs.AccountForTenantRq;
import com.jeequan.jeepay.mgr.rqrs.ReportRequest;
import com.jeequan.jeepay.mgr.rqrs.Page;
import com.jeequan.jeepay.mgr.service.PageService;
import com.jeequan.jeepay.mgr.service.ReportingService;
import com.jeequan.jeepay.mgr.util.EnumTime;
import com.jeequan.jeepay.mgr.util.JxlsUtils;

import com.jeequan.jeepay.mgr.util.TimeUtil;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 报表下载
 *
 * @author chengzw
 * @site https://www.jeequan.com
 * @date 2023/03/17 17:09
 */
@RestController
@RequestMapping("/api/report")
public class ReportController extends CommonCtrl {

    private final ReportingService reportingService;

    public ReportController(ReportingService reportingService) {
        this.reportingService = reportingService;
    }

    //下载文件名
    private final String FILENAMEPREFIX = "集团物业入驻企业%s费用账单";

    //企业账单模板文件
    private final String TENANTTEMPLATE = "TEMPLATE_TENANT-1-1.xlsx";

    //商户账单模板文件
    private final String MECHANTTEMPLATE = "TEMPLATE_TENANT-2.xlsx";

    //订单流水模块文件
    private final String ORDERFLOWTEMPLATE = "TEMPLATE_ORDER_FLOW.xlsx";

    @PreAuthorize("hasAuthority('ENT_REPORT_MANAGER')")
    @RequestMapping(value = "/tenant", method = RequestMethod.POST)
    public void doReport(HttpServletRequest request) throws BizException, IOException {

        String sheetTitle = "";

        ReportRequest reportRequest = getObject(ReportRequest.class);

        EnumTime.TIMETYPE timeType = EnumTime.TIMETYPE.get(reportRequest.getReportType());
        MutablePair<String, String> mutablePair = new MutablePair<>();

        if (timeType.equals(EnumTime.TIMETYPE.YEAR)) {
            mutablePair = TimeUtil.getYearRange(getValIntegerRequired("year"));
            sheetTitle = String.format("%d年度", getValIntegerRequired("year"));

        } else if (timeType.equals(EnumTime.TIMETYPE.MONTH)) {
            mutablePair = TimeUtil.getMonthRange(getValIntegerRequired("year"), getValIntegerRequired("month"));
            sheetTitle = String.format("%d月份", getValIntegerRequired("month"));

        } else if (timeType.equals(EnumTime.TIMETYPE.WEEK)) {
            mutablePair = TimeUtil.getWeekRange(getValIntegerRequired("year"), getValIntegerRequired("weekOfYear"));
            sheetTitle = String.format("第%d周", getValIntegerRequired("weekOfYear"));

        } else if (timeType.equals(EnumTime.TIMETYPE.DAY)) {
            mutablePair = TimeUtil.getDayRange(getValIntegerRequired("year"), getValIntegerRequired("month"), getValIntegerRequired("dayOfMonth"));
            sheetTitle = String.format("%d月%d日", getValIntegerRequired("month"), getValIntegerRequired("dayOfMonth"));

        } else if (timeType.equals(EnumTime.TIMETYPE.OTHER)) {
            mutablePair = MutablePair.of(getValStringRequired("timeStart"), getValStringRequired("timeEnd"));
            sheetTitle = "[" + String.join("~", mutablePair.left.substring(0, 10), mutablePair.right.substring(0, 10)) + "]";

        }

        List<AccountForTenantRq> accountForTenantRqs = reportingService.getAccountForTenants(mutablePair.left, mutablePair.right);
        if (accountForTenantRqs.size() > 0) {
            accountForTenantRqs = accountForTenantRqs.stream().sorted(Comparator.comparing(AccountForTenantRq::getGroupName)).collect(Collectors.toList());
        }

        List<String> sheetNames = accountForTenantRqs.stream().map(item -> item.getGroupName()).collect(Collectors.toList());

        //数据分页转换
        List<Page> page1 = PageService.individual(accountForTenantRqs, sheetNames);
        List<Page> page2 = page1.stream().filter(item -> ((AccountForTenantRq) item.getOnlyOne()).getAccountForDepartmentRqs().stream()
                        .filter(s -> s.getOrgAccountDetailMap().size() > 0 || s.getTypeDetailMap().size() > 0)
                        .findAny().isPresent())
                .collect(Collectors.toList());

        Map<String, Object> model = new HashMap<String, Object>();
        model.put("sheetTitle", sheetTitle);
        model.put("pages_one", page1);
        model.put("pages_two", page2);
        model.put("sheetNames_1", getSheetName(page1, true));
        model.put("sheetNames_2", getSheetName(page1, false));

        if(reportRequest.getRequestType()==1){

            JSONObject result = new JSONObject();
            result.put("records", accountForTenantRqs);  //记录明细
            result.put("total", accountForTenantRqs.size());  //总条数
            result.put("current", 1);  //当前页码
            result.put("hasNext",false);  //是否有下一页

            String outPutJson= ApiRes.ok(result).toJSONString();
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            response.getWriter().write(outPutJson);
            response.getWriter().flush();
            response.getWriter().close();
        }else if(reportRequest.getRequestType()==2){

            // 模板位置，输出流
            ServletOutputStream outputStream = null;
            InputStream in = this.getClass().getClassLoader().getResourceAsStream("templates/" + TENANTTEMPLATE);

            try {

                String fileName = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now()) + ".xlsx";
                response.setContentType("application/octet-stream");
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));

                outputStream = response.getOutputStream();

                JxlsUtils.exportExcel(in, outputStream, model);

            } finally {

                if (in != null) {
                    in.close();
                }
                if (outputStream != null) {
                    outputStream.flush();
                    outputStream.close();
                }
            }
        }

    }


    @PreAuthorize("hasAuthority('ENT_REPORT_MERCHANT')")
    @RequestMapping(value = "/merchant", method = RequestMethod.POST)
    public void doReportFlow(HttpServletRequest request) throws BizException, IOException {

        String sheetTitle = "";
        ReportRequest reportRequest = getObject(ReportRequest.class);

        EnumTime.TIMETYPE timeType = EnumTime.TIMETYPE.get(reportRequest.getReportType());
        MutablePair<String, String> mutablePair = new MutablePair<>();

        if (timeType.equals(EnumTime.TIMETYPE.YEAR)) {
            mutablePair = TimeUtil.getYearRange(getValIntegerRequired("year"));
            sheetTitle = String.format("%d年度", getValIntegerRequired("year"));

        } else if (timeType.equals(EnumTime.TIMETYPE.MONTH)) {
            mutablePair = TimeUtil.getMonthRange(getValIntegerRequired("year"), getValIntegerRequired("month"));
            sheetTitle = String.format("%d月份", getValIntegerRequired("month"));

        } else if (timeType.equals(EnumTime.TIMETYPE.WEEK)) {
            mutablePair = TimeUtil.getWeekRange(getValIntegerRequired("year"), getValIntegerRequired("weekOfYear"));
            sheetTitle = String.format("第%d周", getValIntegerRequired("weekOfYear"));

        } else if (timeType.equals(EnumTime.TIMETYPE.DAY)) {
            mutablePair = TimeUtil.getDayRange(getValIntegerRequired("year"), getValIntegerRequired("month"), getValIntegerRequired("dayOfMonth"));
            sheetTitle = String.format("%d月%d日", getValIntegerRequired("month"), getValIntegerRequired("dayOfMonth"));

        } else if (timeType.equals(EnumTime.TIMETYPE.OTHER)) {
            mutablePair = MutablePair.of(getValStringRequired("timeStart"), getValStringRequired("timeEnd"));
            sheetTitle = "[" + String.join("~", mutablePair.left.substring(0, 10), mutablePair.right.substring(0, 10)) + "]";
        }

        Map<String, Object> model = reportingService.getRentOrder(mutablePair.left, mutablePair.right, reportRequest.getDealTypes(), reportRequest.getAppArray());
        model.put("sheetTitle", sheetTitle);
        model.put("reportTime",new Date());

        ServletOutputStream outputStream = null;
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("templates/" + ORDERFLOWTEMPLATE);

        if(reportRequest.getRequestType()==1){

            JSONObject result = new JSONObject();
            result.put("records", model);  //记录明细
            result.put("total", model.size());  //总条数
            result.put("current", 1);  //当前页码
            result.put("hasNext", false);  //是否有下一页

            String outPutJson= ApiRes.ok(result).toJSONString();
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            response.getWriter().write(outPutJson);
            response.getWriter().flush();
            response.getWriter().close();
        }else if(reportRequest.getRequestType()==2){

            try {
                String fileName = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now()) + ".xlsx";
                response.setContentType("application/octet-stream");
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
                outputStream = response.getOutputStream();

                JxlsUtils.exportExcel(in, outputStream, model);

            } finally {

                if (in != null) {
                    in.close();
                }
                if (outputStream != null) {
                    outputStream.flush();
                    outputStream.close();
                }
            }
        }

    }

    /**
     * 设置excel的工作簿名称
     */
    private ArrayList<String> getSheetName(List<Page> page, Boolean isTotal) {

        String title = isTotal ? "汇总账单" : "部门明细账单";

        ArrayList<String> al = new ArrayList<String>();

        for (int i = 0; i < page.size(); i++) {
            al.add(String.format("%s%s", page.get(i).getSheetName(), title));
        }
        return al;
    }

}